From b460b58f96310693a06cd180b45c3d5d60c778de Mon Sep 17 00:00:00 2001
From: Simon Gardling <titaniumtown@gmail.com>
Date: Wed, 16 Feb 2022 10:08:55 -0500
Subject: [PATCH 01/10] update all dependencies (except for nom)

Upstream: <https://github.com/rekka/meval-rs/pull/27>.

---
 Cargo.toml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml
index 1b8a828..c395833 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -14,14 +14,14 @@ exclude = ["README.tpl", ".travis.yml"]
 [dependencies]
 fnv = "1.0.5"
 nom = "1.0.0"
-serde = { version = "1", optional = true }
+serde = { version = "1.0.136", optional = true }
 
 [dev-dependencies]
-gnuplot = "0.0.23"
-serde_test = "1"
+gnuplot = "0.0.37"
+serde_test = "1.0.136"
 serde_derive = "1"
 serde_json = "1"
-toml = "0.4.5"
+toml = "0.5.8"
 
 [features]
 default = []

From 978dbcf905bd7d051079e4bc197d75ebd8c9c162 Mon Sep 17 00:00:00 2001
From: Ishaan <whthownothing@gmail.com>
Date: Fri, 21 Jan 2022 20:53:17 +0530
Subject: [PATCH 02/10] removed depracation warnings and substituted

---
 src/expr.rs      | 26 +++++++++++++-------------
 src/lib.rs       | 18 ++++--------------
 src/tokenizer.rs | 11 +++++------
 3 files changed, 22 insertions(+), 33 deletions(-)

diff --git a/src/expr.rs b/src/expr.rs
index 23d56ce..f6b303c 100644
--- a/src/expr.rs
+++ b/src/expr.rs
@@ -156,7 +156,7 @@ impl Expr {
     where
         C: ContextProvider + 'a,
     {
-        try!(self.check_context(((var, 0.), &ctx)));
+        self.check_context(((var, 0.), &ctx))?;
         let var = var.to_owned();
         Ok(move |x| {
             self.eval_with_context(((&var, x), &ctx))
@@ -194,7 +194,7 @@ impl Expr {
     where
         C: ContextProvider + 'a,
     {
-        try!(self.check_context(([(var1, 0.), (var2, 0.)], &ctx)));
+        self.check_context(([(var1, 0.), (var2, 0.)], &ctx))?;
         let var1 = var1.to_owned();
         let var2 = var2.to_owned();
         Ok(move |x, y| {
@@ -239,7 +239,7 @@ impl Expr {
     where
         C: ContextProvider + 'a,
     {
-        try!(self.check_context(([(var1, 0.), (var2, 0.), (var3, 0.)], &ctx)));
+        self.check_context(([(var1, 0.), (var2, 0.), (var3, 0.)], &ctx))?;
         let var1 = var1.to_owned();
         let var2 = var2.to_owned();
         let var3 = var3.to_owned();
@@ -287,7 +287,7 @@ impl Expr {
     where
         C: ContextProvider + 'a,
     {
-        try!(self.check_context(([(var1, 0.), (var2, 0.), (var3, 0.), (var4, 0.)], &ctx)));
+        self.check_context(([(var1, 0.), (var2, 0.), (var3, 0.), (var4, 0.)], &ctx))?;
         let var1 = var1.to_owned();
         let var2 = var2.to_owned();
         let var3 = var3.to_owned();
@@ -338,10 +338,10 @@ impl Expr {
     where
         C: ContextProvider + 'a,
     {
-        try!(self.check_context((
+        self.check_context((
             [(var1, 0.), (var2, 0.), (var3, 0.), (var4, 0.), (var5, 0.)],
             &ctx
-        )));
+        ))?;
         let var1 = var1.to_owned();
         let var2 = var2.to_owned();
         let var3 = var3.to_owned();
@@ -389,12 +389,12 @@ impl Expr {
         C: ContextProvider + 'a,
     {
         let n = vars.len();
-        try!(self.check_context((
+        self.check_context((
             vars.into_iter()
                 .zip(vec![0.; n].into_iter())
                 .collect::<Vec<_>>(),
             &ctx
-        )));
+        ))?;
         let vars = vars.iter().map(|v| v.to_owned()).collect::<Vec<_>>();
         Ok(move |x: &[f64]| {
             self.eval_with_context((
@@ -447,7 +447,7 @@ impl Expr {
 
 /// Evaluates a string with built-in constants and functions.
 pub fn eval_str<S: AsRef<str>>(expr: S) -> Result<f64, Error> {
-    let expr = try!(Expr::from_str(expr.as_ref()));
+    let expr = Expr::from_str(expr.as_ref())?;
 
     expr.eval_with_context(builtin())
 }
@@ -456,9 +456,9 @@ impl FromStr for Expr {
     type Err = Error;
     /// Constructs an expression by parsing a string.
     fn from_str(s: &str) -> Result<Self, Self::Err> {
-        let tokens = try!(tokenize(s));
+        let tokens = tokenize(s)?;
 
-        let rpn = try!(to_rpn(&tokens));
+        let rpn = to_rpn(&tokens)?;
 
         Ok(Expr { rpn: rpn })
     }
@@ -471,7 +471,7 @@ pub fn eval_str_with_context<S: AsRef<str>, C: ContextProvider>(
     expr: S,
     ctx: C,
 ) -> Result<f64, Error> {
-    let expr = try!(Expr::from_str(expr.as_ref()));
+    let expr = Expr::from_str(expr.as_ref())?;
 
     expr.eval_with_context(ctx)
 }
@@ -856,7 +856,7 @@ impl<'a> Default for Context<'a> {
     }
 }
 
-type GuardedFunc<'a> = Rc<Fn(&[f64]) -> Result<f64, FuncEvalError> + 'a>;
+type GuardedFunc<'a> = Rc<dyn Fn(&[f64]) -> Result<f64, FuncEvalError> + 'a>;
 
 /// Trait for types that can specify the number of required arguments for a function with a
 /// variable number of arguments.
diff --git a/src/lib.rs b/src/lib.rs
index 2aea3b7..0c8d20d 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -233,15 +233,15 @@ impl fmt::Display for Error {
                 write!(f, "Evaluation error: function `{}`: {}", name, e)
             }
             Error::ParseError(ref e) => {
-                try!(write!(f, "Parse error: "));
+                write!(f, "Parse error: ")?;
                 e.fmt(f)
             }
             Error::RPNError(ref e) => {
-                try!(write!(f, "RPN error: "));
+                write!(f, "RPN error: ")?;
                 e.fmt(f)
             }
             Error::EvalError(ref e) => {
-                try!(write!(f, "Eval error: "));
+                write!(f, "Eval error: ")?;
                 e.fmt(f)
             }
         }
@@ -261,17 +261,7 @@ impl From<RPNError> for Error {
 }
 
 impl std::error::Error for Error {
-    fn description(&self) -> &str {
-        match *self {
-            Error::UnknownVariable(_) => "unknown variable",
-            Error::Function(_, _) => "function evaluation error",
-            Error::EvalError(_) => "eval error",
-            Error::ParseError(ref e) => e.description(),
-            Error::RPNError(ref e) => e.description(),
-        }
-    }
-
-    fn cause(&self) -> Option<&std::error::Error> {
+    fn cause(&self) -> Option<&dyn std::error::Error> {
         match *self {
             Error::ParseError(ref e) => Some(e),
             Error::RPNError(ref e) => Some(e),
diff --git a/src/tokenizer.rs b/src/tokenizer.rs
index d4692e3..f63fcf3 100644
--- a/src/tokenizer.rs
+++ b/src/tokenizer.rs
@@ -5,8 +5,7 @@
 //! The parser should tokenize only well-formed expressions.
 //!
 //! [nom]: https://crates.io/crates/nom
-use nom::{multispace, slice_to_offsets, IResult, Needed};
-use std;
+use nom::{Needed, multispace, slice_to_offsets, IResult};
 use std::fmt;
 use std::str::from_utf8;
 
@@ -117,16 +116,16 @@ named!(comma<Token>, chain!(tag!(","), || Token::Comma));
 fn ident(input: &[u8]) -> IResult<&[u8], &[u8]> {
     use nom::Err::*;
     use nom::IResult::*;
-    use nom::{ErrorKind, Needed};
+    use nom::ErrorKind;
 
     // first character must be 'a'...'z' | 'A'...'Z' | '_'
     match input.first().cloned() {
-        Some(b'a'...b'z') | Some(b'A'...b'Z') | Some(b'_') => {
+        Some(b'a'..=b'z') | Some(b'A'..=b'Z') | Some(b'_') => {
             let n = input
                 .iter()
                 .skip(1)
                 .take_while(|&&c| match c {
-                    b'a'...b'z' | b'A'...b'Z' | b'_' | b'0'...b'9' => true,
+                    b'a'..=b'z' | b'A'..=b'Z' | b'_' | b'0'..=b'9' => true,
                     _ => false,
                 })
                 .count();
@@ -145,7 +144,7 @@ named!(
     ))
 );
 
-/// Parse `func(`, returns `func`.
+// Parse `func(`, returns `func`.
 named!(
     func<Token>,
     map!(

From 9cd8b3dd90acfa6281e0c326719de6cbf532fa7f Mon Sep 17 00:00:00 2001
From: Simon Gardling <titaniumtown@gmail.com>
Date: Wed, 16 Feb 2022 10:21:33 -0500
Subject: [PATCH 03/10] bump even more dependencies

---
 Cargo.toml | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml
index c395833..2cc0eb4 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -12,15 +12,15 @@ version = "0.2.0"
 exclude = ["README.tpl", ".travis.yml"]
 
 [dependencies]
-fnv = "1.0.5"
+fnv = "1.0.7"
 nom = "1.0.0"
 serde = { version = "1.0.136", optional = true }
 
 [dev-dependencies]
 gnuplot = "0.0.37"
 serde_test = "1.0.136"
-serde_derive = "1"
-serde_json = "1"
+serde_derive = "1.0.136"
+serde_json = "1.0.79"
 toml = "0.5.8"
 
 [features]

From 595ea70b5901d48bd119e9d98aa1e84849ec1945 Mon Sep 17 00:00:00 2001
From: Simon Gardling <titaniumtown@gmail.com>
Date: Wed, 16 Feb 2022 10:34:18 -0500
Subject: [PATCH 04/10] nom 7.1.0

based on work from: https://github.com/rekka/meval-rs/pull/22
---
 Cargo.toml           |   2 +-
 src/lib.rs           |   8 +-
 src/shunting_yard.rs |   1 +
 src/tokenizer.rs     | 749 ++++++++++++++++++++++++++++---------------
 4 files changed, 496 insertions(+), 264 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml
index 2cc0eb4..60b4064 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,7 +13,7 @@ exclude = ["README.tpl", ".travis.yml"]
 
 [dependencies]
 fnv = "1.0.7"
-nom = "1.0.0"
+nom = "7.1.0"
 serde = { version = "1.0.136", optional = true }
 
 [dev-dependencies]
diff --git a/src/lib.rs b/src/lib.rs
index 0c8d20d..69261b1 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -208,7 +208,7 @@ pub mod de;
 
 pub use expr::*;
 pub use shunting_yard::RPNError;
-pub use tokenizer::ParseError;
+pub use tokenizer::TokenParseError;
 
 /// An error produced during parsing or evaluation.
 #[derive(Debug, Clone, PartialEq)]
@@ -216,7 +216,7 @@ pub enum Error {
     UnknownVariable(String),
     Function(String, FuncEvalError),
     /// An error returned by the parser.
-    ParseError(ParseError),
+    ParseError(TokenParseError),
     /// The shunting-yard algorithm returned an error.
     RPNError(RPNError),
     // A catch all for all other errors during evaluation
@@ -248,8 +248,8 @@ impl fmt::Display for Error {
     }
 }
 
-impl From<ParseError> for Error {
-    fn from(err: ParseError) -> Error {
+impl From<TokenParseError> for Error {
+    fn from(err: TokenParseError) -> Error {
         Error::ParseError(err)
     }
 }
diff --git a/src/shunting_yard.rs b/src/shunting_yard.rs
index 5fe3010..90026bf 100644
--- a/src/shunting_yard.rs
+++ b/src/shunting_yard.rs
@@ -1,3 +1,4 @@
+
 //! Implementation of the shunting-yard algorithm for converting an infix expression to an
 //! expression in reverse Polish notation (RPN).
 //!
diff --git a/src/tokenizer.rs b/src/tokenizer.rs
index f63fcf3..0e08337 100644
--- a/src/tokenizer.rs
+++ b/src/tokenizer.rs
@@ -5,44 +5,66 @@
 //! The parser should tokenize only well-formed expressions.
 //!
 //! [nom]: https://crates.io/crates/nom
-use nom::{Needed, multispace, slice_to_offsets, IResult};
+
+use nom::{
+  branch::alt,
+  bytes::complete::is_a,
+  bytes::complete::{escaped, take, tag, take_while},
+  character::complete::{anychar, digit1, multispace0, alphanumeric1, alphanumeric0, char, alpha1, one_of},
+  combinator::{complete, peek, all_consuming, recognize, map, opt, cut, not},
+  error::{context, convert_error, ErrorKind, ParseError, VerboseError},
+  multi::separated_list0,
+  number::complete::double,
+  sequence::{tuple, pair, delimited, preceded, separated_pair, terminated},
+  Err, Needed, IResult
+};
+
 use std::fmt;
 use std::str::from_utf8;
+use std::f64;
 
 /// An error reported by the parser.
 #[derive(Debug, Clone, PartialEq)]
-pub enum ParseError {
+pub enum TokenParseError {
     /// A token that is not allowed at the given location (contains the location of the offending
     /// character in the source string).
     UnexpectedToken(usize),
+
+    UnexpectedStrToken(String),
     /// Missing right parentheses at the end of the source string (contains the number of missing
     /// parens).
     MissingRParen(i32),
     /// Missing operator or function argument at the end of the expression.
     MissingArgument,
+
+    UnknownError
 }
 
-impl fmt::Display for ParseError {
+impl fmt::Display for TokenParseError {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        match *self {
-            ParseError::UnexpectedToken(i) => write!(f, "Unexpected token at byte {}.", i),
-            ParseError::MissingRParen(i) => write!(
+        match &*self {
+            TokenParseError::UnexpectedToken(i) => write!(f, "Unexpected token at byte {}.", i),
+            TokenParseError::UnexpectedStrToken(s) => write!(f, "Unexpected token {}.", s),
+            TokenParseError::MissingRParen(i) => write!(
                 f,
                 "Missing {} right parenthes{}.",
                 i,
-                if i == 1 { "is" } else { "es" }
+                if *i == 1 { "is" } else { "es" }
             ),
-            ParseError::MissingArgument => write!(f, "Missing argument at the end of expression."),
+            TokenParseError::MissingArgument => write!(f, "Missing argument at the end of expression."),
+            TokenParseError::UnknownError => write!(f, "Unknown pass error."),
         }
     }
 }
 
-impl std::error::Error for ParseError {
+impl std::error::Error for TokenParseError {
     fn description(&self) -> &str {
         match *self {
-            ParseError::UnexpectedToken(_) => "unexpected token",
-            ParseError::MissingRParen(_) => "missing right parenthesis",
-            ParseError::MissingArgument => "missing argument",
+            TokenParseError::UnexpectedToken(_) => "unexpected token",
+            TokenParseError::UnexpectedStrToken(_) => "Unexpected token",
+            TokenParseError::MissingRParen(_) => "missing right parenthesis",
+            TokenParseError::MissingArgument => "missing argument",
+            TokenParseError::UnknownError => "unknown error",
         }
     }
 }
@@ -73,6 +95,8 @@ pub enum Token {
     RParen,
     /// Comma: function argument separator
     Comma,
+    /// Decimal Point 
+    //DecimalPoint,
 
     /// A number.
     Number(f64),
@@ -82,179 +106,150 @@ pub enum Token {
     Func(String, Option<usize>),
 }
 
-named!(
-    binop<Token>,
-    alt!(
-        chain!(tag!("+"), || Token::Binary(Operation::Plus))
-            | chain!(tag!("-"), || Token::Binary(Operation::Minus))
-            | chain!(tag!("*"), || Token::Binary(Operation::Times))
-            | chain!(tag!("/"), || Token::Binary(Operation::Div))
-            | chain!(tag!("%"), || Token::Binary(Operation::Rem))
-            | chain!(tag!("^"), || Token::Binary(Operation::Pow))
-    )
-);
-
-named!(
-    negpos<Token>,
-    alt!(
-        chain!(tag!("+"), || Token::Unary(Operation::Plus))
-            | chain!(tag!("-"), || Token::Unary(Operation::Minus))
-    )
-);
-
-named!(
-    fact<Token>,
-    chain!(tag!("!"), || Token::Unary(Operation::Fact))
-);
-named!(lparen<Token>, chain!(tag!("("), || Token::LParen));
-named!(rparen<Token>, chain!(tag!(")"), || Token::RParen));
-named!(comma<Token>, chain!(tag!(","), || Token::Comma));
-
-/// Parse an identifier:
-///
-/// Must start with a letter or an underscore, can be followed by letters, digits or underscores.
-fn ident(input: &[u8]) -> IResult<&[u8], &[u8]> {
-    use nom::Err::*;
-    use nom::IResult::*;
-    use nom::ErrorKind;
-
-    // first character must be 'a'...'z' | 'A'...'Z' | '_'
-    match input.first().cloned() {
-        Some(b'a'..=b'z') | Some(b'A'..=b'Z') | Some(b'_') => {
-            let n = input
-                .iter()
-                .skip(1)
-                .take_while(|&&c| match c {
-                    b'a'..=b'z' | b'A'..=b'Z' | b'_' | b'0'..=b'9' => true,
-                    _ => false,
-                })
-                .count();
-            let (parsed, rest) = input.split_at(n + 1);
-            Done(rest, parsed)
-        }
-        None => Incomplete(Needed::Size(1)),
-        _ => Error(Position(ErrorKind::Custom(0), input)),
-    }
+/// Continuing the trend of starting from the simplest piece and building up,
+/// we start by creating a parser for the built-in operator functions.
+fn binop<'a>(i: &'a str) -> IResult<&'a str, Token, (&'a str, ErrorKind)> {
+  // one_of matches one of the characters we give it
+  let (i, t) = one_of("+-*/%^!")(i)?;
+
+  // because we are matching single character tokens, we can do the matching logic
+  // on the returned value
+  Ok((
+    i,
+    match t {
+      '+' => Token::Binary(Operation::Plus),
+      '-' => Token::Binary(Operation::Minus),
+      '*' => Token::Binary(Operation::Times),
+      '/' => Token::Binary(Operation::Div),
+      '%' => Token::Binary(Operation::Rem),
+      '^' => Token::Binary(Operation::Pow),
+      '!' => Token::Binary(Operation::Fact),
+      _ => unreachable!(),
+    },
+  ))
 }
 
-named!(
-    var<Token>,
-    map!(map_res!(complete!(ident), from_utf8), |s: &str| Token::Var(
-        s.into()
-    ))
-);
-
-// Parse `func(`, returns `func`.
-named!(
-    func<Token>,
-    map!(
-        map_res!(
-            terminated!(
-                complete!(ident),
-                preceded!(opt!(multispace), complete!(tag!("(")))
-            ),
-            from_utf8
-        ),
-        |s: &str| Token::Func(s.into(), None)
-    )
-);
+fn lparen<'a>(i: &'a str) -> IResult<&'a str, Token, (&'a str, ErrorKind)> {
+    map(tag("("), |_: &str| Token::LParen)(i)
+}
 
-/// Matches one or more digit characters `0`...`9`.
-///
-/// Never returns `nom::IResult::Incomplete`.
-///
-/// Fix of IMHO broken `nom::digit`, which parses an empty string successfully.
-fn digit_complete(input: &[u8]) -> IResult<&[u8], &[u8]> {
-    use nom::Err::*;
-    use nom::IResult::*;
-    use nom::{is_digit, ErrorKind};
-
-    let n = input.iter().take_while(|&&c| is_digit(c)).count();
-    if n > 0 {
-        let (parsed, rest) = input.split_at(n);
-        Done(rest, parsed)
-    } else {
-        Error(Position(ErrorKind::Digit, input))
+fn rparen<'a>(i: &'a str) -> IResult<&'a str, Token, (&'a str, ErrorKind)> {
+    map(tag(")"), |_: &str| Token::RParen)(i)
+}
+
+fn comma<'a>(i: &'a str) -> IResult<&'a str, Token, (&'a str, ErrorKind)> {
+    map(tag(","), |_: &str| Token::Comma)(i)
+}
+
+/// negpos parse. detects either - or +
+fn negpos_s<'a>(i: &'a str) -> IResult<&'a str, &'a str, (&'a str, ErrorKind)> {
+ 
+    match alt((tag("+"), tag("-"), ))(i) {
+        Ok((remaining_input, operator)) => Ok((remaining_input, operator)),
+		Err(e) => Err(e)
     }
 }
 
-named!(
-    float<usize>,
-    chain!(
-        a: digit_complete ~
-        b: complete!(chain!(tag!(".") ~ d: digit_complete?,
-                            ||{1 + d.map(|s| s.len()).unwrap_or(0)}))? ~
-        e: complete!(exp),
-        ||{a.len() + b.unwrap_or(0) + e.unwrap_or(0)}
-    )
-);
-
-/// Parser that matches the exponential part of a float. If the `input[0] == 'e' | 'E'` then at
-/// least one digit must match.
-fn exp(input: &[u8]) -> IResult<&[u8], Option<usize>> {
-    use nom::IResult::*;
-    match alt!(input, tag!("e") | tag!("E")) {
-        Incomplete(_) | Error(_) => Done(input, None),
-        Done(i, _) => match chain!(i, s: alt!(tag!("+") | tag!("-"))? ~
-                   e: digit_complete,
-                ||{Some(1 + s.map(|s| s.len()).unwrap_or(0) + e.len())})
-        {
-            Incomplete(Needed::Size(i)) => Incomplete(Needed::Size(i + 1)),
-            o => o,
+/// negpos parse. detects either - or +
+fn negpos<'a>(i: &'a str) -> IResult<&'a str, Token, (&'a str, ErrorKind)> {
+
+    match negpos_s(i)  {
+        Ok((remaining_input, operator)) => {
+            match operator.as_ref() {
+                "+" => Ok((remaining_input, Token::Unary(Operation::Plus))),
+                "-" => Ok((remaining_input, Token::Unary(Operation::Minus))),
+                _ => panic!("Should never occur")
+            }
         },
+		Err(e) => Err(e)
     }
 }
 
-fn number(input: &[u8]) -> IResult<&[u8], Token> {
-    use nom::Err;
-    use nom::ErrorKind;
-    use nom::IResult::*;
-    use std::str::FromStr;
-
-    match float(input) {
-        Done(rest, l) => {
-            // it should be safe to call unwrap here instead of the error checking, since
-            // `float` should match only well-formed numbers
-            from_utf8(&input[..l])
-                .ok()
-                .and_then(|s| f64::from_str(s).ok())
-                .map_or(Error(Err::Position(ErrorKind::Custom(0), input)), |f| {
-                    Done(rest, Token::Number(f))
-                })
-        }
-        Error(e) => Error(e),
-        Incomplete(n) => Incomplete(n),
-    }
+/// factorial parse
+fn fact<'a>(i: &'a str) -> IResult<&'a str, Token, (&'a str, ErrorKind)> {
+    map(tag("!"), |s: &str| Token::Unary(Operation::Fact))(i)
 }
 
-named!(
-    lexpr<Token>,
-    delimited!(
-        opt!(multispace),
-        alt!(number | func | var | negpos | lparen),
-        opt!(multispace)
-    )
-);
-named!(
-    after_rexpr<Token>,
-    delimited!(
-        opt!(multispace),
-        alt!(fact | binop | rparen),
-        opt!(multispace)
-    )
-);
-named!(
-    after_rexpr_no_paren<Token>,
-    delimited!(opt!(multispace), alt!(fact | binop), opt!(multispace))
-);
-named!(
-    after_rexpr_comma<Token>,
-    delimited!(
-        opt!(multispace),
-        alt!(fact | binop | rparen | comma),
-        opt!(multispace)
-    )
-);
+fn ident<'a>(i: &'a str) -> IResult<&'a str, &'a str, (&'a str, ErrorKind)> {
+    let REMAINING_CHARS: &str = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+    let FIRST_CHARS: &str = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
+  
+    // Returns whole strings matched by the given parser.
+    recognize(
+      // Runs the first parser, if succeeded then runs second, and returns the second result.
+      // Note that returned ok value of `preceded()` is ignored by `recognize()`.
+      preceded(
+        // Parses a single character contained in the given string.
+        one_of(FIRST_CHARS),
+        // Parses the longest slice consisting of the given characters
+        opt(is_a(REMAINING_CHARS)),
+      )
+    )(i)
+  }
+
+fn var<'a>(i: &'a str) -> IResult<&'a str, Token, (&'a str, ErrorKind)> {
+    map(complete(ident), |s: &str| Token::Var(s.into()))(i)
+}
+
+/// Parse `func(`, returns `func`.
+fn func<'a>(i: &'a str) -> IResult<&'a str, Token, (&'a str, ErrorKind)> {
+  map(
+    //recognize(
+        terminated(
+            complete(ident),
+            preceded(multispace0,
+                     complete(tag("("))
+            )
+        )
+    //)
+        ,
+        |s: &str| Token::Func(s.into(), None)
+    )(i)
+}
+
+fn number<'a>(i: &'a str) -> IResult<&'a str, Token, (&'a str, ErrorKind)> {
+    preceded(
+        peek(one_of("0123456789")),
+        map(double, |s| Token::Number(s))
+    )(i)
+}
+
+fn lexpr<'a>(i: &'a str) -> IResult<&'a str, Token, (&'a str, ErrorKind)> {
+
+    delimited(
+          multispace0,
+          alt((number, func, var, negpos, lparen)),
+          multispace0
+    )(i)
+}
+
+
+fn after_rexpr<'a>(i: &'a str) -> IResult<&'a str, Token, (&'a str, ErrorKind)> {
+
+    delimited(
+          multispace0,
+          alt((fact, binop, rparen)),
+          multispace0
+    )(i)
+}
+
+fn after_rexpr_no_paren<'a>(i: &'a str) -> IResult<&'a str, Token, (&'a str, ErrorKind)> {
+
+    delimited(
+          multispace0,
+          alt((fact, binop)),
+          multispace0
+    )(i)
+}
+
+fn after_rexpr_comma<'a>(i: &'a str) -> IResult<&'a str, Token, (&'a str, ErrorKind)> {
+
+    delimited(
+          multispace0,
+          alt((fact, binop, rparen, comma)),
+          multispace0
+    )(i)
+}
 
 #[derive(Debug, Clone, Copy)]
 enum TokenizerState {
@@ -270,6 +265,7 @@ enum ParenState {
     Func,
 }
 
+
 /// Tokenize a given mathematical expression.
 ///
 /// The parser should return `Ok` only if the expression is well-formed.
@@ -277,29 +273,27 @@ enum ParenState {
 /// # Failure
 ///
 /// Returns `Err` if the expression is not well-formed.
-pub fn tokenize<S: AsRef<str>>(input: S) -> Result<Vec<Token>, ParseError> {
-    use self::TokenizerState::*;
-    use nom::Err;
-    use nom::IResult::*;
-    let mut state = LExpr;
+pub fn tokenize(input: &str) -> Result<Vec<Token>, TokenParseError> {
+    let mut state: TokenizerState = TokenizerState::LExpr;
     // number of function arguments left
     let mut paren_stack = vec![];
 
     let mut res = vec![];
 
-    let input = input.as_ref().as_bytes();
     let mut s = input;
 
     while !s.is_empty() {
+
         let r = match (state, paren_stack.last()) {
-            (LExpr, _) => lexpr(s),
-            (AfterRExpr, None) => after_rexpr_no_paren(s),
-            (AfterRExpr, Some(&ParenState::Subexpr)) => after_rexpr(s),
-            (AfterRExpr, Some(&ParenState::Func)) => after_rexpr_comma(s),
+            (TokenizerState::LExpr, _) => lexpr(s),
+            (TokenizerState::AfterRExpr, None) => after_rexpr_no_paren(s),
+            (TokenizerState::AfterRExpr, Some(&ParenState::Subexpr)) => after_rexpr(s),
+            (TokenizerState::AfterRExpr, Some(&ParenState::Func)) => after_rexpr_comma(s),
         };
 
         match r {
-            Done(rest, t) => {
+            Ok((rest, t)) => {
+
                 match t {
                     Token::LParen => {
                         paren_stack.push(ParenState::Subexpr);
@@ -311,133 +305,366 @@ pub fn tokenize<S: AsRef<str>>(input: S) -> Result<Vec<Token>, ParseError> {
                         paren_stack.pop().expect("The paren_stack is empty!");
                     }
                     Token::Var(_) | Token::Number(_) => {
-                        state = AfterRExpr;
+                        state = TokenizerState::AfterRExpr;
                     }
                     Token::Binary(_) | Token::Comma => {
-                        state = LExpr;
+                        state = TokenizerState::LExpr;
                     }
                     _ => {}
                 }
                 res.push(t);
                 s = rest;
             }
-            Error(Err::Position(_, p)) => {
-                let (i, _) = slice_to_offsets(input, p);
-                return Err(ParseError::UnexpectedToken(i));
+            Err(e) => {
+        
+                match e {
+                    Err::Error((value, _)) => {
+                        return Err(TokenParseError::UnexpectedStrToken(value.to_string()));
+                    },
+                    _ => (),
+                }
+
+                return Err(TokenParseError::UnknownError);
             }
+            // Error(Err::Position(_, p)) => {
+            //     let (i, _) = slice_to_offsets(input, p);
+            //     return Err(TokenParseError::UnexpectedToken(i));
+            // }
             _ => {
-                panic!(
-                    "Unexpected parse result when parsing `{}` at `{}`: {:?}",
-                    String::from_utf8_lossy(input),
-                    String::from_utf8_lossy(s),
-                    r
-                );
+                panic!("Unexpected parse result when parsing `{}` at `{}`: {:?}", input, s, r);
             }
         }
+
     }
 
     match state {
-        LExpr => Err(ParseError::MissingArgument),
-        _ if !paren_stack.is_empty() => Err(ParseError::MissingRParen(paren_stack.len() as i32)),
-        _ => Ok(res),
+        TokenizerState::LExpr => {
+            Err(TokenParseError::MissingArgument)
+        },
+
+        _ => {
+            if !paren_stack.is_empty() {
+                return Err(TokenParseError::MissingRParen(paren_stack.len() as i32));
+            }
+
+            return Ok(res);
+        }
     }
+
+
 }
 
+
+
+
+// ok rest ["+(3--2) "]   t Number(2.0)
+// ok rest ["(3--2) "]   t Binary(Plus)
+// ok rest [51, 45, 45, 50, 41, 32]   t LParen
+// ok rest [45, 45, 50, 41, 32]   t Number(3.0)
+// ok rest [45, 50, 41, 32]   t Binary(Minus)
+// ok rest [50, 41, 32]   t Unary(Minus)
+// ok rest [") "]   t Number(2.0)
+// ok rest []   t RParen
+// state: AfterRExpr
+// paren_stack: []
+// Ok([Number(2.0), Binary(Plus), LParen, Number(3.0), Binary(Minus), Unary(Minus), Number(2.0), RParen])
+
+
 #[cfg(test)]
 mod tests {
     use super::*;
-    use super::{binop, func, number, var};
-    use nom::Err::*;
-    use nom::ErrorKind::*;
-    use nom::IResult;
-
+ 
     #[test]
     fn it_works() {
+
+        assert_eq!(
+            binop("+"),
+            Ok(("", Token::Binary(Operation::Plus)))
+        );
+        assert_eq!(
+            ident("abc32"),
+            Ok(("", "abc32"))
+        );
+        assert_eq!(
+            func("abc("),
+            Ok(("", Token::Func("abc".into(), None)))
+        );
+        assert_eq!(
+            func("abc ("),
+            Ok(("", Token::Func("abc".into(), None)))
+        );
+        assert_eq!(
+            var("abc"),
+            Ok(("", Token::Var("abc".into())))
+        );
+        assert_eq!(
+            fact("!"),
+            Ok(("", Token::Unary(Operation::Fact)))
+        );
+        assert_eq!(
+            negpos_s("+"),
+            Ok(("", "+"))
+        );
+        assert_eq!(
+            negpos_s("-"),
+            Ok(("", "-"))
+        );
+        assert_eq!(
+            negpos_s("+362"),
+            Ok(("362", "+"))
+        );
+        assert_eq!(
+            negpos_s("-5734"),
+            Ok(("5734", "-"))
+        );
+        assert_eq!(
+            negpos("+"),
+            Ok(("", Token::Unary(Operation::Plus)))
+        );
+        assert_eq!(
+            negpos("-"),
+            Ok(("", Token::Unary(Operation::Minus)))
+        );
+        assert_eq!(
+            negpos("+642"),
+            Ok(("642", Token::Unary(Operation::Plus)))
+        );
+        assert_eq!(
+            negpos("-563"),
+            Ok(("563", Token::Unary(Operation::Minus)))
+        );
+        assert_eq!(
+            lparen("("),
+            Ok(("", Token::LParen))
+        );
+        assert_eq!(
+            rparen(")"),
+            Ok(("", Token::RParen))
+        );
+        assert_eq!(
+            comma(","),
+            Ok(("", Token::Comma))
+        );
         assert_eq!(
-            binop(b"+"),
-            IResult::Done(&b""[..], Token::Binary(Operation::Plus))
+            comma(","),
+            Ok(("", Token::Comma))
         );
         assert_eq!(
-            number(b"32143"),
-            IResult::Done(&b""[..], Token::Number(32143f64))
+            number("+1.34e2"),
+            Ok(("", Token::Number(134.0)))
         );
         assert_eq!(
-            var(b"abc"),
-            IResult::Done(&b""[..], Token::Var("abc".into()))
+            number("+1.34e+2"),
+            Ok(("", Token::Number(134.0)))
         );
         assert_eq!(
-            func(b"abc("),
-            IResult::Done(&b""[..], Token::Func("abc".into(), None))
+            number("3E+2"),
+            Ok(("", Token::Number(300.0)))
         );
         assert_eq!(
-            func(b"abc ("),
-            IResult::Done(&b""[..], Token::Func("abc".into(), None))
+            number("+4E+2"),
+            Ok(("", Token::Number(400.0)))
+        );
+        assert_eq!(
+            number("-4.76E+2"),
+            Ok(("", Token::Number(-476.0)))
+        );
+        assert_eq!(
+            number("-4.76"),
+            Ok(("", Token::Number(-4.76)))
+        );
+        assert_eq!(
+            number("+4.76"),
+            Ok(("", Token::Number(4.76)))
+        );
+        assert_eq!(
+            number("1.1"),
+            Ok(("", Token::Number(1.1)))
+        );
+        assert_eq!(
+            number("-1.1"),
+            Ok(("", Token::Number(-1.1)))
+        );
+        assert_eq!(
+            number("123E-02"),
+            Ok(("", Token::Number(1.23)))
+        );
+        assert_eq!(
+            number("+123E-02"),
+            Ok(("", Token::Number(1.23)))
+        );
+        assert_eq!(
+            number("-123E-02"),
+            Ok(("", Token::Number(-1.23)))
+        );
+        assert_eq!(
+            number("abc"),
+            Err(Err::Error(("abc", nom::error::ErrorKind::Float)))
         );
     }
 
     #[test]
-    fn test_var() {
-        for &s in ["abc", "U0", "_034", "a_be45EA", "aAzZ_"].iter() {
-            assert_eq!(
-                var(s.as_bytes()),
-                IResult::Done(&b""[..], Token::Var(s.into()))
-            );
-        }
+    fn test_lexpr() {
+
+        // number, func, var, negpos, lparen
+        assert_eq!(
+            number("a"),
+            Err(Err::Error(("a", nom::error::ErrorKind::Float)))
+        );
+
+        assert_eq!(
+            func("a"),
+            Err(Err::Error(("", nom::error::ErrorKind::Tag)))
+        );
+
+        assert_eq!(
+            var("a"),
+            Ok(("", Token::Var("a".into())))
+        );
+
+        assert_eq!(
+            lexpr("a"),
+            Ok(("", Token::Var("a".into())))
+        );
+
+        assert_eq!(
+            lexpr("2+"),
+            Ok(("+", Token::Number(2.0)))
+        );
+
+        assert_eq!(
+            lexpr("2 +(3--2) "),
+            Ok(("+(3--2) ", Token::Number(2.0)))
+        );
+        
+
+        println!("{:?}", number("+(3--2) "));
+
+        assert_eq!(
+            lexpr("+(3--2) "),
+            Ok(("+(3--2) ", Token::Binary(Operation::Plus)))
+        );
 
-        assert_eq!(var(b""), IResult::Error(Position(Complete, &b""[..])));
-        assert_eq!(var(b"0"), IResult::Error(Position(Custom(0), &b"0"[..])));
     }
 
     #[test]
-    fn test_func() {
-        for &s in ["abc(", "u0(", "_034 (", "A_be45EA  ("].iter() {
+    fn test_var() {
+        for &s in ["abc", "U0", "_034", "a_be45EA", "aAzZ_"].iter() {
             assert_eq!(
-                func(s.as_bytes()),
-                IResult::Done(
-                    &b""[..],
-                    Token::Func((&s[0..s.len() - 1]).trim().into(), None)
-                )
+                var(s),
+                Ok(("", Token::Var(s.into())))
             );
         }
 
-        assert_eq!(func(b""), IResult::Error(Position(Complete, &b""[..])));
-        assert_eq!(func(b"("), IResult::Error(Position(Custom(0), &b"("[..])));
-        assert_eq!(func(b"0("), IResult::Error(Position(Custom(0), &b"0("[..])));
+        assert_eq!(var(""), Err(Err::Error(("", nom::error::ErrorKind::OneOf))));
+        assert_eq!(var("0"), Err(Err::Error(("0", nom::error::ErrorKind::OneOf))));
     }
 
     #[test]
     fn test_number() {
+
+        assert_eq!(
+            number("45"),
+            Ok(("", Token::Number(45.0)))
+        );
+
+        assert_eq!(
+            number("+(3--2) "),
+            Err(Err::Error(("+(3--2) ", nom::error::ErrorKind::OneOf)))
+        );
+
+        assert_eq!(
+            number("+3 "),
+            Err(Err::Error(("+3 ", nom::error::ErrorKind::OneOf)))
+        );
+
         assert_eq!(
-            number(b"32143"),
-            IResult::Done(&b""[..], Token::Number(32143f64))
+            number("(3--2) "),
+            Err(Err::Error(("(3--2) ", nom::error::ErrorKind::OneOf)))
+        );
+
+        assert_eq!(
+            number("(3) "),
+            Err(Err::Error(("(3) ", nom::error::ErrorKind::OneOf)))
+        );
+        assert_eq!(
+            number("(3) - (2) "),
+            Err(Err::Error(("(3) - (2) ", nom::error::ErrorKind::OneOf)))
+        );
+        assert_eq!(
+            number("32143"),
+            Ok(("", Token::Number(32143f64)))
+        );
+        assert_eq!(
+            number("2."),
+            Ok(("", Token::Number(2.0f64)))
         );
         assert_eq!(
-            number(b"2."),
-            IResult::Done(&b""[..], Token::Number(2.0f64))
+            number("32143.25"),
+            Ok(("", Token::Number(32143.25f64)))
         );
         assert_eq!(
-            number(b"32143.25"),
-            IResult::Done(&b""[..], Token::Number(32143.25f64))
+            number("0.125e9"),
+            Ok(("", Token::Number(0.125e9f64)))
         );
         assert_eq!(
-            number(b"0.125e9"),
-            IResult::Done(&b""[..], Token::Number(0.125e9f64))
+            number("20.5E-3"),
+            Ok(("", Token::Number(20.5E-3f64)))
         );
         assert_eq!(
-            number(b"20.5E-3"),
-            IResult::Done(&b""[..], Token::Number(20.5E-3f64))
+            number("123423e+50"),
+            Ok(("", Token::Number(123423e+50f64)))
         );
         assert_eq!(
-            number(b"123423e+50"),
-            IResult::Done(&b""[..], Token::Number(123423e+50f64))
+            number("0.2"),
+            Ok(("", Token::Number(0.2)))
         );
+        assert_eq!(
+            number(""),
+            Err(Err::Error(("", nom::error::ErrorKind::OneOf)))
+        );
+        assert_eq!(
+            number("+"),
+            Err(Err::Error(("+", nom::error::ErrorKind::OneOf)))
+        );
+        assert_eq!(
+            number("e"),
+            Err(Err::Error(("e", nom::error::ErrorKind::OneOf)))
+        );
+        assert_eq!(
+            number("1E"),
+            Err(Err::Error(("E", nom::error::ErrorKind::Eof)))
+        );
+        assert_eq!(
+            number("1e"),
+            Err(Err::Error(("e", nom::error::ErrorKind::Eof)))
+        );
+        assert_eq!(
+            number("1e+"),
+            Err(Err::Error(("+", nom::error::ErrorKind::Eof)))
+        );
+        assert_eq!(
+            number("1e+-?%"),
+            Err(Err::Error(("-?%", nom::error::ErrorKind::Eof)))
+        );
+        assert_eq!(
+            number("2+"),
+            Err(Err::Error(("+", nom::error::ErrorKind::Eof)))
+        );
+    }
 
-        assert_eq!(number(b""), IResult::Error(Position(Digit, &b""[..])));
-        assert_eq!(number(b".2"), IResult::Error(Position(Digit, &b".2"[..])));
-        assert_eq!(number(b"+"), IResult::Error(Position(Digit, &b"+"[..])));
-        assert_eq!(number(b"e"), IResult::Error(Position(Digit, &b"e"[..])));
-        assert_eq!(number(b"1E"), IResult::Error(Position(Complete, &b"E"[..])));
-        assert_eq!(number(b"1e+"), IResult::Error(Position(Digit, &b""[..])));
+    #[test]
+    fn test_func() {
+        for &s in ["abc(", "u0(", "_034 (", "A_be45EA  ("].iter() {
+            assert_eq!(
+                func(s),
+                Ok(("", Token::Func((&s[0..s.len() - 1]).trim().into(), None)))
+            );
+        }
+
+        assert_eq!(func(""), Err(Err::Error(("", nom::error::ErrorKind::OneOf))));
+        assert_eq!(func("("), Err(Err::Error(("(", nom::error::ErrorKind::OneOf))));
+        assert_eq!(func("0("), Err(Err::Error(("0(", nom::error::ErrorKind::OneOf))));
     }
 
     #[test]
@@ -445,6 +672,10 @@ mod tests {
         use super::Operation::*;
         use super::Token::*;
 
+        // Ok([Number(2.0), Binary(Plus), Number(2.0), Binary(Div), Number(3.0), Binary(Minus), Number(56.0), Binary(Plus), Func("sin", None), Number(3.0), RParen])
+        // Ok([Number(2.0), Binary(Plus), Number(2.0), Binary(Div), Number(3.0), Binary(Minus), Number(56.0), Binary(Plus), Func("sin", None), Number(3.0), RParen])
+        println!("{:?}", tokenize("2 + 2/3-56 + sin(3)"));
+
         assert_eq!(tokenize("a"), Ok(vec![Var("a".into())]));
 
         assert_eq!(
@@ -522,15 +753,15 @@ mod tests {
             ])
         );
 
-        assert_eq!(tokenize("!3"), Err(ParseError::UnexpectedToken(0)));
+        assert_eq!(tokenize("!3"), Err(TokenParseError::UnexpectedStrToken("!3".to_string())));
 
-        assert_eq!(tokenize("()"), Err(ParseError::UnexpectedToken(1)));
+        assert_eq!(tokenize("()"), Err(TokenParseError::UnexpectedStrToken(")".to_string())));
 
-        assert_eq!(tokenize(""), Err(ParseError::MissingArgument));
-        assert_eq!(tokenize("2)"), Err(ParseError::UnexpectedToken(1)));
-        assert_eq!(tokenize("2^"), Err(ParseError::MissingArgument));
-        assert_eq!(tokenize("(((2)"), Err(ParseError::MissingRParen(2)));
-        assert_eq!(tokenize("f(2,)"), Err(ParseError::UnexpectedToken(4)));
-        assert_eq!(tokenize("f(,2)"), Err(ParseError::UnexpectedToken(2)));
+        assert_eq!(tokenize(""), Err(TokenParseError::MissingArgument));
+        assert_eq!(tokenize("2)"), Err(TokenParseError::UnexpectedStrToken(")".to_string())));
+        assert_eq!(tokenize("2^"), Err(TokenParseError::MissingArgument));
+        assert_eq!(tokenize("(((2)"), Err(TokenParseError::MissingRParen(2)));
+        assert_eq!(tokenize("f(2,)"), Err(TokenParseError::UnexpectedStrToken(")".to_string())));
+        assert_eq!(tokenize("f(,2)"), Err(TokenParseError::UnexpectedStrToken(",2)".to_string())));
     }
-}
+}
\ No newline at end of file

From f888f42034a37f0f8a41fe88d091246ff4b8a574 Mon Sep 17 00:00:00 2001
From: Simon Gardling <titaniumtown@gmail.com>
Date: Wed, 16 Feb 2022 10:39:10 -0500
Subject: [PATCH 05/10] clippy

---
 src/expr.rs       | 22 +++++++++++-----------
 src/extra_math.rs | 10 +++++-----
 src/tokenizer.rs  | 25 ++++++++++++-------------
 3 files changed, 28 insertions(+), 29 deletions(-)

diff --git a/src/expr.rs b/src/expr.rs
index f6b303c..c151756 100644
--- a/src/expr.rs
+++ b/src/expr.rs
@@ -390,7 +390,7 @@ impl Expr {
     {
         let n = vars.len();
         self.check_context((
-            vars.into_iter()
+            vars.iter()
                 .zip(vec![0.; n].into_iter())
                 .collect::<Vec<_>>(),
             &ctx
@@ -399,7 +399,7 @@ impl Expr {
         Ok(move |x: &[f64]| {
             self.eval_with_context((
                 vars.iter()
-                    .zip(x.into_iter())
+                    .zip(x.iter())
                     .map(|(v, x)| (v, *x))
                     .collect::<Vec<_>>(),
                 &ctx,
@@ -460,7 +460,7 @@ impl FromStr for Expr {
 
         let rpn = to_rpn(&tokens)?;
 
-        Ok(Expr { rpn: rpn })
+        Ok(Expr { rpn })
     }
 }
 
@@ -599,21 +599,21 @@ pub fn builtin<'a>() -> Context<'a> {
 
 impl<'a, T: ContextProvider> ContextProvider for &'a T {
     fn get_var(&self, name: &str) -> Option<f64> {
-        (&**self).get_var(name)
+        (**self).get_var(name)
     }
 
     fn eval_func(&self, name: &str, args: &[f64]) -> Result<f64, FuncEvalError> {
-        (&**self).eval_func(name, args)
+        (**self).eval_func(name, args)
     }
 }
 
 impl<'a, T: ContextProvider> ContextProvider for &'a mut T {
     fn get_var(&self, name: &str) -> Option<f64> {
-        (&**self).get_var(name)
+        (**self).get_var(name)
     }
 
     fn eval_func(&self, name: &str, args: &[f64]) -> Result<f64, FuncEvalError> {
-        (&**self).eval_func(name, args)
+        (**self).eval_func(name, args)
     }
 }
 
@@ -1170,20 +1170,20 @@ mod tests {
         );
 
         let expr = Expr::from_str("x + y^2 + z^3").unwrap();
-        let func = expr.clone().bind3("x", "y", "z").unwrap();
+        let func = expr.bind3("x", "y", "z").unwrap();
         assert_eq!(func(1., 2., 3.), 32.);
 
         let expr = Expr::from_str("sin(x)").unwrap();
-        let func = expr.clone().bind("x").unwrap();
+        let func = expr.bind("x").unwrap();
         assert_eq!(func(1.), (1f64).sin());
 
         let expr = Expr::from_str("sin(x,2)").unwrap();
-        match expr.clone().bind("x") {
+        match expr.bind("x") {
             Err(Error::Function(_, FuncEvalError::NumberArgs(1))) => {}
             _ => panic!("bind did not error"),
         }
         let expr = Expr::from_str("hey(x,2)").unwrap();
-        match expr.clone().bind("x") {
+        match expr.bind("x") {
             Err(Error::Function(_, FuncEvalError::UnknownFunction)) => {}
             _ => panic!("bind did not error"),
         }
diff --git a/src/extra_math.rs b/src/extra_math.rs
index 63b6296..39d31f7 100644
--- a/src/extra_math.rs
+++ b/src/extra_math.rs
@@ -2,19 +2,19 @@
 // This is to take advantage of the fact that std::f64::MAX >>> std::u64::MAX
 fn factorial_unsafe(num: f64) -> f64 {
     if num == 0. || num == 1. {
-        return 1.;
+        1.
     } else {
-        return num * factorial_unsafe(num - 1.);
+        num * factorial_unsafe(num - 1.)
     }
 }
 
 pub fn factorial(num: f64) -> Result<f64, &'static str> {
     if num.fract() != 0. || num < 0. {
-        return Err("Number must be non-negative with no fractional component!");
+        Err("Number must be non-negative with no fractional component!")
     } else if num > 170. {
-        return Ok(std::f64::INFINITY);
+        Ok(std::f64::INFINITY)
     } else {
-        return Ok(factorial_unsafe(num));
+        Ok(factorial_unsafe(num))
     }
 }
 
diff --git a/src/tokenizer.rs b/src/tokenizer.rs
index 0e08337..322eb15 100644
--- a/src/tokenizer.rs
+++ b/src/tokenizer.rs
@@ -9,18 +9,17 @@
 use nom::{
   branch::alt,
   bytes::complete::is_a,
-  bytes::complete::{escaped, take, tag, take_while},
-  character::complete::{anychar, digit1, multispace0, alphanumeric1, alphanumeric0, char, alpha1, one_of},
-  combinator::{complete, peek, all_consuming, recognize, map, opt, cut, not},
-  error::{context, convert_error, ErrorKind, ParseError, VerboseError},
-  multi::separated_list0,
+  bytes::complete::{tag},
+  character::complete::{multispace0, one_of},
+  combinator::{complete, peek, recognize, map, opt},
+  error::{ErrorKind},
   number::complete::double,
-  sequence::{tuple, pair, delimited, preceded, separated_pair, terminated},
-  Err, Needed, IResult
+  sequence::{delimited, preceded, terminated},
+  Err, IResult
 };
 
 use std::fmt;
-use std::str::from_utf8;
+
 use std::f64;
 
 /// An error reported by the parser.
@@ -155,7 +154,7 @@ fn negpos<'a>(i: &'a str) -> IResult<&'a str, Token, (&'a str, ErrorKind)> {
 
     match negpos_s(i)  {
         Ok((remaining_input, operator)) => {
-            match operator.as_ref() {
+            match operator {
                 "+" => Ok((remaining_input, Token::Unary(Operation::Plus))),
                 "-" => Ok((remaining_input, Token::Unary(Operation::Minus))),
                 _ => panic!("Should never occur")
@@ -167,7 +166,7 @@ fn negpos<'a>(i: &'a str) -> IResult<&'a str, Token, (&'a str, ErrorKind)> {
 
 /// factorial parse
 fn fact<'a>(i: &'a str) -> IResult<&'a str, Token, (&'a str, ErrorKind)> {
-    map(tag("!"), |s: &str| Token::Unary(Operation::Fact))(i)
+    map(tag("!"), |_s: &str| Token::Unary(Operation::Fact))(i)
 }
 
 fn ident<'a>(i: &'a str) -> IResult<&'a str, &'a str, (&'a str, ErrorKind)> {
@@ -210,7 +209,7 @@ fn func<'a>(i: &'a str) -> IResult<&'a str, Token, (&'a str, ErrorKind)> {
 fn number<'a>(i: &'a str) -> IResult<&'a str, Token, (&'a str, ErrorKind)> {
     preceded(
         peek(one_of("0123456789")),
-        map(double, |s| Token::Number(s))
+        map(double, Token::Number)
     )(i)
 }
 
@@ -347,7 +346,7 @@ pub fn tokenize(input: &str) -> Result<Vec<Token>, TokenParseError> {
                 return Err(TokenParseError::MissingRParen(paren_stack.len() as i32));
             }
 
-            return Ok(res);
+            Ok(res)
         }
     }
 
@@ -658,7 +657,7 @@ mod tests {
         for &s in ["abc(", "u0(", "_034 (", "A_be45EA  ("].iter() {
             assert_eq!(
                 func(s),
-                Ok(("", Token::Func((&s[0..s.len() - 1]).trim().into(), None)))
+                Ok(("", Token::Func(s[0..s.len() - 1].trim().into(), None)))
             );
         }
 

From ad90ef78e9986dbd3c84a0743706384b433a4d38 Mon Sep 17 00:00:00 2001
From: Simon Gardling <titaniumtown@gmail.com>
Date: Wed, 16 Feb 2022 10:39:18 -0500
Subject: [PATCH 06/10] rustfmt

---
 src/expr.rs          |   8 +-
 src/shunting_yard.rs |   1 -
 src/tokenizer.rs     | 447 +++++++++++++++----------------------------
 3 files changed, 152 insertions(+), 304 deletions(-)

diff --git a/src/expr.rs b/src/expr.rs
index c151756..04b54b5 100644
--- a/src/expr.rs
+++ b/src/expr.rs
@@ -340,7 +340,7 @@ impl Expr {
     {
         self.check_context((
             [(var1, 0.), (var2, 0.), (var3, 0.), (var4, 0.), (var5, 0.)],
-            &ctx
+            &ctx,
         ))?;
         let var1 = var1.to_owned();
         let var2 = var2.to_owned();
@@ -390,10 +390,8 @@ impl Expr {
     {
         let n = vars.len();
         self.check_context((
-            vars.iter()
-                .zip(vec![0.; n].into_iter())
-                .collect::<Vec<_>>(),
-            &ctx
+            vars.iter().zip(vec![0.; n].into_iter()).collect::<Vec<_>>(),
+            &ctx,
         ))?;
         let vars = vars.iter().map(|v| v.to_owned()).collect::<Vec<_>>();
         Ok(move |x: &[f64]| {
diff --git a/src/shunting_yard.rs b/src/shunting_yard.rs
index 90026bf..5fe3010 100644
--- a/src/shunting_yard.rs
+++ b/src/shunting_yard.rs
@@ -1,4 +1,3 @@
-
 //! Implementation of the shunting-yard algorithm for converting an infix expression to an
 //! expression in reverse Polish notation (RPN).
 //!
diff --git a/src/tokenizer.rs b/src/tokenizer.rs
index 322eb15..190fa51 100644
--- a/src/tokenizer.rs
+++ b/src/tokenizer.rs
@@ -7,15 +7,15 @@
 //! [nom]: https://crates.io/crates/nom
 
 use nom::{
-  branch::alt,
-  bytes::complete::is_a,
-  bytes::complete::{tag},
-  character::complete::{multispace0, one_of},
-  combinator::{complete, peek, recognize, map, opt},
-  error::{ErrorKind},
-  number::complete::double,
-  sequence::{delimited, preceded, terminated},
-  Err, IResult
+    branch::alt,
+    bytes::complete::is_a,
+    bytes::complete::tag,
+    character::complete::{multispace0, one_of},
+    combinator::{complete, map, opt, peek, recognize},
+    error::ErrorKind,
+    number::complete::double,
+    sequence::{delimited, preceded, terminated},
+    Err, IResult,
 };
 
 use std::fmt;
@@ -36,7 +36,7 @@ pub enum TokenParseError {
     /// Missing operator or function argument at the end of the expression.
     MissingArgument,
 
-    UnknownError
+    UnknownError,
 }
 
 impl fmt::Display for TokenParseError {
@@ -50,7 +50,9 @@ impl fmt::Display for TokenParseError {
                 i,
                 if *i == 1 { "is" } else { "es" }
             ),
-            TokenParseError::MissingArgument => write!(f, "Missing argument at the end of expression."),
+            TokenParseError::MissingArgument => {
+                write!(f, "Missing argument at the end of expression.")
+            }
             TokenParseError::UnknownError => write!(f, "Unknown pass error."),
         }
     }
@@ -94,7 +96,7 @@ pub enum Token {
     RParen,
     /// Comma: function argument separator
     Comma,
-    /// Decimal Point 
+    /// Decimal Point
     //DecimalPoint,
 
     /// A number.
@@ -108,24 +110,24 @@ pub enum Token {
 /// Continuing the trend of starting from the simplest piece and building up,
 /// we start by creating a parser for the built-in operator functions.
 fn binop<'a>(i: &'a str) -> IResult<&'a str, Token, (&'a str, ErrorKind)> {
-  // one_of matches one of the characters we give it
-  let (i, t) = one_of("+-*/%^!")(i)?;
-
-  // because we are matching single character tokens, we can do the matching logic
-  // on the returned value
-  Ok((
-    i,
-    match t {
-      '+' => Token::Binary(Operation::Plus),
-      '-' => Token::Binary(Operation::Minus),
-      '*' => Token::Binary(Operation::Times),
-      '/' => Token::Binary(Operation::Div),
-      '%' => Token::Binary(Operation::Rem),
-      '^' => Token::Binary(Operation::Pow),
-      '!' => Token::Binary(Operation::Fact),
-      _ => unreachable!(),
-    },
-  ))
+    // one_of matches one of the characters we give it
+    let (i, t) = one_of("+-*/%^!")(i)?;
+
+    // because we are matching single character tokens, we can do the matching logic
+    // on the returned value
+    Ok((
+        i,
+        match t {
+            '+' => Token::Binary(Operation::Plus),
+            '-' => Token::Binary(Operation::Minus),
+            '*' => Token::Binary(Operation::Times),
+            '/' => Token::Binary(Operation::Div),
+            '%' => Token::Binary(Operation::Rem),
+            '^' => Token::Binary(Operation::Pow),
+            '!' => Token::Binary(Operation::Fact),
+            _ => unreachable!(),
+        },
+    ))
 }
 
 fn lparen<'a>(i: &'a str) -> IResult<&'a str, Token, (&'a str, ErrorKind)> {
@@ -142,25 +144,21 @@ fn comma<'a>(i: &'a str) -> IResult<&'a str, Token, (&'a str, ErrorKind)> {
 
 /// negpos parse. detects either - or +
 fn negpos_s<'a>(i: &'a str) -> IResult<&'a str, &'a str, (&'a str, ErrorKind)> {
- 
-    match alt((tag("+"), tag("-"), ))(i) {
+    match alt((tag("+"), tag("-")))(i) {
         Ok((remaining_input, operator)) => Ok((remaining_input, operator)),
-		Err(e) => Err(e)
+        Err(e) => Err(e),
     }
 }
 
 /// negpos parse. detects either - or +
 fn negpos<'a>(i: &'a str) -> IResult<&'a str, Token, (&'a str, ErrorKind)> {
-
-    match negpos_s(i)  {
-        Ok((remaining_input, operator)) => {
-            match operator {
-                "+" => Ok((remaining_input, Token::Unary(Operation::Plus))),
-                "-" => Ok((remaining_input, Token::Unary(Operation::Minus))),
-                _ => panic!("Should never occur")
-            }
+    match negpos_s(i) {
+        Ok((remaining_input, operator)) => match operator {
+            "+" => Ok((remaining_input, Token::Unary(Operation::Plus))),
+            "-" => Ok((remaining_input, Token::Unary(Operation::Minus))),
+            _ => panic!("Should never occur"),
         },
-		Err(e) => Err(e)
+        Err(e) => Err(e),
     }
 }
 
@@ -172,19 +170,19 @@ fn fact<'a>(i: &'a str) -> IResult<&'a str, Token, (&'a str, ErrorKind)> {
 fn ident<'a>(i: &'a str) -> IResult<&'a str, &'a str, (&'a str, ErrorKind)> {
     let REMAINING_CHARS: &str = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
     let FIRST_CHARS: &str = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
-  
+
     // Returns whole strings matched by the given parser.
     recognize(
-      // Runs the first parser, if succeeded then runs second, and returns the second result.
-      // Note that returned ok value of `preceded()` is ignored by `recognize()`.
-      preceded(
-        // Parses a single character contained in the given string.
-        one_of(FIRST_CHARS),
-        // Parses the longest slice consisting of the given characters
-        opt(is_a(REMAINING_CHARS)),
-      )
+        // Runs the first parser, if succeeded then runs second, and returns the second result.
+        // Note that returned ok value of `preceded()` is ignored by `recognize()`.
+        preceded(
+            // Parses a single character contained in the given string.
+            one_of(FIRST_CHARS),
+            // Parses the longest slice consisting of the given characters
+            opt(is_a(REMAINING_CHARS)),
+        ),
     )(i)
-  }
+}
 
 fn var<'a>(i: &'a str) -> IResult<&'a str, Token, (&'a str, ErrorKind)> {
     map(complete(ident), |s: &str| Token::Var(s.into()))(i)
@@ -192,62 +190,35 @@ fn var<'a>(i: &'a str) -> IResult<&'a str, Token, (&'a str, ErrorKind)> {
 
 /// Parse `func(`, returns `func`.
 fn func<'a>(i: &'a str) -> IResult<&'a str, Token, (&'a str, ErrorKind)> {
-  map(
-    //recognize(
-        terminated(
-            complete(ident),
-            preceded(multispace0,
-                     complete(tag("("))
-            )
-        )
-    //)
-        ,
-        |s: &str| Token::Func(s.into(), None)
+    map(
+        //recognize(
+        terminated(complete(ident), preceded(multispace0, complete(tag("(")))), //)
+        |s: &str| Token::Func(s.into(), None),
     )(i)
 }
 
 fn number<'a>(i: &'a str) -> IResult<&'a str, Token, (&'a str, ErrorKind)> {
-    preceded(
-        peek(one_of("0123456789")),
-        map(double, Token::Number)
-    )(i)
+    preceded(peek(one_of("0123456789")), map(double, Token::Number))(i)
 }
 
 fn lexpr<'a>(i: &'a str) -> IResult<&'a str, Token, (&'a str, ErrorKind)> {
-
     delimited(
-          multispace0,
-          alt((number, func, var, negpos, lparen)),
-          multispace0
+        multispace0,
+        alt((number, func, var, negpos, lparen)),
+        multispace0,
     )(i)
 }
 
-
 fn after_rexpr<'a>(i: &'a str) -> IResult<&'a str, Token, (&'a str, ErrorKind)> {
-
-    delimited(
-          multispace0,
-          alt((fact, binop, rparen)),
-          multispace0
-    )(i)
+    delimited(multispace0, alt((fact, binop, rparen)), multispace0)(i)
 }
 
 fn after_rexpr_no_paren<'a>(i: &'a str) -> IResult<&'a str, Token, (&'a str, ErrorKind)> {
-
-    delimited(
-          multispace0,
-          alt((fact, binop)),
-          multispace0
-    )(i)
+    delimited(multispace0, alt((fact, binop)), multispace0)(i)
 }
 
 fn after_rexpr_comma<'a>(i: &'a str) -> IResult<&'a str, Token, (&'a str, ErrorKind)> {
-
-    delimited(
-          multispace0,
-          alt((fact, binop, rparen, comma)),
-          multispace0
-    )(i)
+    delimited(multispace0, alt((fact, binop, rparen, comma)), multispace0)(i)
 }
 
 #[derive(Debug, Clone, Copy)]
@@ -264,7 +235,6 @@ enum ParenState {
     Func,
 }
 
-
 /// Tokenize a given mathematical expression.
 ///
 /// The parser should return `Ok` only if the expression is well-formed.
@@ -282,7 +252,6 @@ pub fn tokenize(input: &str) -> Result<Vec<Token>, TokenParseError> {
     let mut s = input;
 
     while !s.is_empty() {
-
         let r = match (state, paren_stack.last()) {
             (TokenizerState::LExpr, _) => lexpr(s),
             (TokenizerState::AfterRExpr, None) => after_rexpr_no_paren(s),
@@ -292,7 +261,6 @@ pub fn tokenize(input: &str) -> Result<Vec<Token>, TokenParseError> {
 
         match r {
             Ok((rest, t)) => {
-
                 match t {
                     Token::LParen => {
                         paren_stack.push(ParenState::Subexpr);
@@ -315,11 +283,10 @@ pub fn tokenize(input: &str) -> Result<Vec<Token>, TokenParseError> {
                 s = rest;
             }
             Err(e) => {
-        
                 match e {
                     Err::Error((value, _)) => {
                         return Err(TokenParseError::UnexpectedStrToken(value.to_string()));
-                    },
+                    }
                     _ => (),
                 }
 
@@ -330,16 +297,16 @@ pub fn tokenize(input: &str) -> Result<Vec<Token>, TokenParseError> {
             //     return Err(TokenParseError::UnexpectedToken(i));
             // }
             _ => {
-                panic!("Unexpected parse result when parsing `{}` at `{}`: {:?}", input, s, r);
+                panic!(
+                    "Unexpected parse result when parsing `{}` at `{}`: {:?}",
+                    input, s, r
+                );
             }
         }
-
     }
 
     match state {
-        TokenizerState::LExpr => {
-            Err(TokenParseError::MissingArgument)
-        },
+        TokenizerState::LExpr => Err(TokenParseError::MissingArgument),
 
         _ => {
             if !paren_stack.is_empty() {
@@ -349,13 +316,8 @@ pub fn tokenize(input: &str) -> Result<Vec<Token>, TokenParseError> {
             Ok(res)
         }
     }
-
-
 }
 
-
-
-
 // ok rest ["+(3--2) "]   t Number(2.0)
 // ok rest ["(3--2) "]   t Binary(Plus)
 // ok rest [51, 45, 45, 50, 41, 32]   t LParen
@@ -368,134 +330,42 @@ pub fn tokenize(input: &str) -> Result<Vec<Token>, TokenParseError> {
 // paren_stack: []
 // Ok([Number(2.0), Binary(Plus), LParen, Number(3.0), Binary(Minus), Unary(Minus), Number(2.0), RParen])
 
-
 #[cfg(test)]
 mod tests {
     use super::*;
- 
+
     #[test]
     fn it_works() {
-
-        assert_eq!(
-            binop("+"),
-            Ok(("", Token::Binary(Operation::Plus)))
-        );
-        assert_eq!(
-            ident("abc32"),
-            Ok(("", "abc32"))
-        );
-        assert_eq!(
-            func("abc("),
-            Ok(("", Token::Func("abc".into(), None)))
-        );
-        assert_eq!(
-            func("abc ("),
-            Ok(("", Token::Func("abc".into(), None)))
-        );
-        assert_eq!(
-            var("abc"),
-            Ok(("", Token::Var("abc".into())))
-        );
-        assert_eq!(
-            fact("!"),
-            Ok(("", Token::Unary(Operation::Fact)))
-        );
-        assert_eq!(
-            negpos_s("+"),
-            Ok(("", "+"))
-        );
-        assert_eq!(
-            negpos_s("-"),
-            Ok(("", "-"))
-        );
-        assert_eq!(
-            negpos_s("+362"),
-            Ok(("362", "+"))
-        );
-        assert_eq!(
-            negpos_s("-5734"),
-            Ok(("5734", "-"))
-        );
-        assert_eq!(
-            negpos("+"),
-            Ok(("", Token::Unary(Operation::Plus)))
-        );
-        assert_eq!(
-            negpos("-"),
-            Ok(("", Token::Unary(Operation::Minus)))
-        );
-        assert_eq!(
-            negpos("+642"),
-            Ok(("642", Token::Unary(Operation::Plus)))
-        );
-        assert_eq!(
-            negpos("-563"),
-            Ok(("563", Token::Unary(Operation::Minus)))
-        );
-        assert_eq!(
-            lparen("("),
-            Ok(("", Token::LParen))
-        );
-        assert_eq!(
-            rparen(")"),
-            Ok(("", Token::RParen))
-        );
-        assert_eq!(
-            comma(","),
-            Ok(("", Token::Comma))
-        );
-        assert_eq!(
-            comma(","),
-            Ok(("", Token::Comma))
-        );
-        assert_eq!(
-            number("+1.34e2"),
-            Ok(("", Token::Number(134.0)))
-        );
-        assert_eq!(
-            number("+1.34e+2"),
-            Ok(("", Token::Number(134.0)))
-        );
-        assert_eq!(
-            number("3E+2"),
-            Ok(("", Token::Number(300.0)))
-        );
-        assert_eq!(
-            number("+4E+2"),
-            Ok(("", Token::Number(400.0)))
-        );
-        assert_eq!(
-            number("-4.76E+2"),
-            Ok(("", Token::Number(-476.0)))
-        );
-        assert_eq!(
-            number("-4.76"),
-            Ok(("", Token::Number(-4.76)))
-        );
-        assert_eq!(
-            number("+4.76"),
-            Ok(("", Token::Number(4.76)))
-        );
-        assert_eq!(
-            number("1.1"),
-            Ok(("", Token::Number(1.1)))
-        );
-        assert_eq!(
-            number("-1.1"),
-            Ok(("", Token::Number(-1.1)))
-        );
-        assert_eq!(
-            number("123E-02"),
-            Ok(("", Token::Number(1.23)))
-        );
-        assert_eq!(
-            number("+123E-02"),
-            Ok(("", Token::Number(1.23)))
-        );
-        assert_eq!(
-            number("-123E-02"),
-            Ok(("", Token::Number(-1.23)))
-        );
+        assert_eq!(binop("+"), Ok(("", Token::Binary(Operation::Plus))));
+        assert_eq!(ident("abc32"), Ok(("", "abc32")));
+        assert_eq!(func("abc("), Ok(("", Token::Func("abc".into(), None))));
+        assert_eq!(func("abc ("), Ok(("", Token::Func("abc".into(), None))));
+        assert_eq!(var("abc"), Ok(("", Token::Var("abc".into()))));
+        assert_eq!(fact("!"), Ok(("", Token::Unary(Operation::Fact))));
+        assert_eq!(negpos_s("+"), Ok(("", "+")));
+        assert_eq!(negpos_s("-"), Ok(("", "-")));
+        assert_eq!(negpos_s("+362"), Ok(("362", "+")));
+        assert_eq!(negpos_s("-5734"), Ok(("5734", "-")));
+        assert_eq!(negpos("+"), Ok(("", Token::Unary(Operation::Plus))));
+        assert_eq!(negpos("-"), Ok(("", Token::Unary(Operation::Minus))));
+        assert_eq!(negpos("+642"), Ok(("642", Token::Unary(Operation::Plus))));
+        assert_eq!(negpos("-563"), Ok(("563", Token::Unary(Operation::Minus))));
+        assert_eq!(lparen("("), Ok(("", Token::LParen)));
+        assert_eq!(rparen(")"), Ok(("", Token::RParen)));
+        assert_eq!(comma(","), Ok(("", Token::Comma)));
+        assert_eq!(comma(","), Ok(("", Token::Comma)));
+        assert_eq!(number("+1.34e2"), Ok(("", Token::Number(134.0))));
+        assert_eq!(number("+1.34e+2"), Ok(("", Token::Number(134.0))));
+        assert_eq!(number("3E+2"), Ok(("", Token::Number(300.0))));
+        assert_eq!(number("+4E+2"), Ok(("", Token::Number(400.0))));
+        assert_eq!(number("-4.76E+2"), Ok(("", Token::Number(-476.0))));
+        assert_eq!(number("-4.76"), Ok(("", Token::Number(-4.76))));
+        assert_eq!(number("+4.76"), Ok(("", Token::Number(4.76))));
+        assert_eq!(number("1.1"), Ok(("", Token::Number(1.1))));
+        assert_eq!(number("-1.1"), Ok(("", Token::Number(-1.1))));
+        assert_eq!(number("123E-02"), Ok(("", Token::Number(1.23))));
+        assert_eq!(number("+123E-02"), Ok(("", Token::Number(1.23))));
+        assert_eq!(number("-123E-02"), Ok(("", Token::Number(-1.23))));
         assert_eq!(
             number("abc"),
             Err(Err::Error(("abc", nom::error::ErrorKind::Float)))
@@ -504,38 +374,21 @@ mod tests {
 
     #[test]
     fn test_lexpr() {
-
         // number, func, var, negpos, lparen
         assert_eq!(
             number("a"),
             Err(Err::Error(("a", nom::error::ErrorKind::Float)))
         );
 
-        assert_eq!(
-            func("a"),
-            Err(Err::Error(("", nom::error::ErrorKind::Tag)))
-        );
+        assert_eq!(func("a"), Err(Err::Error(("", nom::error::ErrorKind::Tag))));
 
-        assert_eq!(
-            var("a"),
-            Ok(("", Token::Var("a".into())))
-        );
+        assert_eq!(var("a"), Ok(("", Token::Var("a".into()))));
 
-        assert_eq!(
-            lexpr("a"),
-            Ok(("", Token::Var("a".into())))
-        );
+        assert_eq!(lexpr("a"), Ok(("", Token::Var("a".into()))));
 
-        assert_eq!(
-            lexpr("2+"),
-            Ok(("+", Token::Number(2.0)))
-        );
+        assert_eq!(lexpr("2+"), Ok(("+", Token::Number(2.0))));
 
-        assert_eq!(
-            lexpr("2 +(3--2) "),
-            Ok(("+(3--2) ", Token::Number(2.0)))
-        );
-        
+        assert_eq!(lexpr("2 +(3--2) "), Ok(("+(3--2) ", Token::Number(2.0))));
 
         println!("{:?}", number("+(3--2) "));
 
@@ -543,29 +396,24 @@ mod tests {
             lexpr("+(3--2) "),
             Ok(("+(3--2) ", Token::Binary(Operation::Plus)))
         );
-
     }
 
     #[test]
     fn test_var() {
         for &s in ["abc", "U0", "_034", "a_be45EA", "aAzZ_"].iter() {
-            assert_eq!(
-                var(s),
-                Ok(("", Token::Var(s.into())))
-            );
+            assert_eq!(var(s), Ok(("", Token::Var(s.into()))));
         }
 
         assert_eq!(var(""), Err(Err::Error(("", nom::error::ErrorKind::OneOf))));
-        assert_eq!(var("0"), Err(Err::Error(("0", nom::error::ErrorKind::OneOf))));
+        assert_eq!(
+            var("0"),
+            Err(Err::Error(("0", nom::error::ErrorKind::OneOf)))
+        );
     }
 
     #[test]
     fn test_number() {
-
-        assert_eq!(
-            number("45"),
-            Ok(("", Token::Number(45.0)))
-        );
+        assert_eq!(number("45"), Ok(("", Token::Number(45.0))));
 
         assert_eq!(
             number("+(3--2) "),
@@ -590,34 +438,13 @@ mod tests {
             number("(3) - (2) "),
             Err(Err::Error(("(3) - (2) ", nom::error::ErrorKind::OneOf)))
         );
-        assert_eq!(
-            number("32143"),
-            Ok(("", Token::Number(32143f64)))
-        );
-        assert_eq!(
-            number("2."),
-            Ok(("", Token::Number(2.0f64)))
-        );
-        assert_eq!(
-            number("32143.25"),
-            Ok(("", Token::Number(32143.25f64)))
-        );
-        assert_eq!(
-            number("0.125e9"),
-            Ok(("", Token::Number(0.125e9f64)))
-        );
-        assert_eq!(
-            number("20.5E-3"),
-            Ok(("", Token::Number(20.5E-3f64)))
-        );
-        assert_eq!(
-            number("123423e+50"),
-            Ok(("", Token::Number(123423e+50f64)))
-        );
-        assert_eq!(
-            number("0.2"),
-            Ok(("", Token::Number(0.2)))
-        );
+        assert_eq!(number("32143"), Ok(("", Token::Number(32143f64))));
+        assert_eq!(number("2."), Ok(("", Token::Number(2.0f64))));
+        assert_eq!(number("32143.25"), Ok(("", Token::Number(32143.25f64))));
+        assert_eq!(number("0.125e9"), Ok(("", Token::Number(0.125e9f64))));
+        assert_eq!(number("20.5E-3"), Ok(("", Token::Number(20.5E-3f64))));
+        assert_eq!(number("123423e+50"), Ok(("", Token::Number(123423e+50f64))));
+        assert_eq!(number("0.2"), Ok(("", Token::Number(0.2))));
         assert_eq!(
             number(""),
             Err(Err::Error(("", nom::error::ErrorKind::OneOf)))
@@ -661,9 +488,18 @@ mod tests {
             );
         }
 
-        assert_eq!(func(""), Err(Err::Error(("", nom::error::ErrorKind::OneOf))));
-        assert_eq!(func("("), Err(Err::Error(("(", nom::error::ErrorKind::OneOf))));
-        assert_eq!(func("0("), Err(Err::Error(("0(", nom::error::ErrorKind::OneOf))));
+        assert_eq!(
+            func(""),
+            Err(Err::Error(("", nom::error::ErrorKind::OneOf)))
+        );
+        assert_eq!(
+            func("("),
+            Err(Err::Error(("(", nom::error::ErrorKind::OneOf)))
+        );
+        assert_eq!(
+            func("0("),
+            Err(Err::Error(("0(", nom::error::ErrorKind::OneOf)))
+        );
     }
 
     #[test]
@@ -752,15 +588,30 @@ mod tests {
             ])
         );
 
-        assert_eq!(tokenize("!3"), Err(TokenParseError::UnexpectedStrToken("!3".to_string())));
+        assert_eq!(
+            tokenize("!3"),
+            Err(TokenParseError::UnexpectedStrToken("!3".to_string()))
+        );
 
-        assert_eq!(tokenize("()"), Err(TokenParseError::UnexpectedStrToken(")".to_string())));
+        assert_eq!(
+            tokenize("()"),
+            Err(TokenParseError::UnexpectedStrToken(")".to_string()))
+        );
 
         assert_eq!(tokenize(""), Err(TokenParseError::MissingArgument));
-        assert_eq!(tokenize("2)"), Err(TokenParseError::UnexpectedStrToken(")".to_string())));
+        assert_eq!(
+            tokenize("2)"),
+            Err(TokenParseError::UnexpectedStrToken(")".to_string()))
+        );
         assert_eq!(tokenize("2^"), Err(TokenParseError::MissingArgument));
         assert_eq!(tokenize("(((2)"), Err(TokenParseError::MissingRParen(2)));
-        assert_eq!(tokenize("f(2,)"), Err(TokenParseError::UnexpectedStrToken(")".to_string())));
-        assert_eq!(tokenize("f(,2)"), Err(TokenParseError::UnexpectedStrToken(",2)".to_string())));
+        assert_eq!(
+            tokenize("f(2,)"),
+            Err(TokenParseError::UnexpectedStrToken(")".to_string()))
+        );
+        assert_eq!(
+            tokenize("f(,2)"),
+            Err(TokenParseError::UnexpectedStrToken(",2)".to_string()))
+        );
     }
-}
\ No newline at end of file
+}

From f6b868d04aa3e034f51dfd322e66c75b6d413e5f Mon Sep 17 00:00:00 2001
From: Simon Gardling <titaniumtown@gmail.com>
Date: Wed, 16 Feb 2022 15:03:07 -0500
Subject: [PATCH 07/10] add 'log' function (does the same thing as log10)

---
 src/expr.rs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/expr.rs b/src/expr.rs
index 04b54b5..ad29be0 100644
--- a/src/expr.rs
+++ b/src/expr.rs
@@ -723,6 +723,7 @@ impl<'a> Context<'a> {
             ctx.func("exp", f64::exp);
             ctx.func("ln", f64::ln);
             ctx.func("log10", f64::log10);
+            ctx.func("log", f64::log10);
             ctx.func("abs", f64::abs);
             ctx.func("sin", f64::sin);
             ctx.func("cos", f64::cos);

From 00cd188a9a2b98a01b686e03ed9c375b2760a0b0 Mon Sep 17 00:00:00 2001
From: Simon Gardling <titaniumtown@gmail.com>
Date: Thu, 17 Feb 2022 11:24:00 -0500
Subject: [PATCH 08/10] update README.md

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 5571842..22d4633 100644
--- a/README.md
+++ b/README.md
@@ -104,7 +104,7 @@ supported:
 - functions implemented using functions of the same name in [Rust std library][std-float]:
 
     - `sqrt`, `abs`
-    - `exp`, `ln`, `log10`
+    - `exp`, `ln`, `log10` (`log10` can also be called as `log`)
     - `sin`, `cos`, `tan`, `asin`, `acos`, `atan`, `atan2`
     - `sinh`, `cosh`, `tanh`, `asinh`, `acosh`, `atanh`
     - `floor`, `ceil`, `round`

From 115b1ef88d57ac827f8f62eff97e026455c32791 Mon Sep 17 00:00:00 2001
From: Simon Gardling <titaniumtown@gmail.com>
Date: Tue, 22 Feb 2022 10:17:50 -0500
Subject: [PATCH 09/10] don't specify specific serde version

---
 Cargo.toml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml
index 60b4064..8d62d0d 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -14,13 +14,13 @@ exclude = ["README.tpl", ".travis.yml"]
 [dependencies]
 fnv = "1.0.7"
 nom = "7.1.0"
-serde = { version = "1.0.136", optional = true }
+serde = { version = "1", optional = true }
 
 [dev-dependencies]
 gnuplot = "0.0.37"
-serde_test = "1.0.136"
-serde_derive = "1.0.136"
-serde_json = "1.0.79"
+serde_test = "1"
+serde_derive = "1"
+serde_json = "1"
 toml = "0.5.8"
 
 [features]

From 6bf579fd402928745cf4f24e5c975bece3285179 Mon Sep 17 00:00:00 2001
From: Simon Gardling <titaniumtown@gmail.com>
Date: Thu, 3 Mar 2022 10:32:47 -0500
Subject: [PATCH 10/10] fix variable naming

---
 src/tokenizer.rs | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/tokenizer.rs b/src/tokenizer.rs
index 190fa51..9dfd304 100644
--- a/src/tokenizer.rs
+++ b/src/tokenizer.rs
@@ -168,8 +168,8 @@ fn fact<'a>(i: &'a str) -> IResult<&'a str, Token, (&'a str, ErrorKind)> {
 }
 
 fn ident<'a>(i: &'a str) -> IResult<&'a str, &'a str, (&'a str, ErrorKind)> {
-    let REMAINING_CHARS: &str = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
-    let FIRST_CHARS: &str = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
+    let remaining_chars: &str = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+    let first_chars: &str = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
 
     // Returns whole strings matched by the given parser.
     recognize(
@@ -177,9 +177,9 @@ fn ident<'a>(i: &'a str) -> IResult<&'a str, &'a str, (&'a str, ErrorKind)> {
         // Note that returned ok value of `preceded()` is ignored by `recognize()`.
         preceded(
             // Parses a single character contained in the given string.
-            one_of(FIRST_CHARS),
+            one_of(first_chars),
             // Parses the longest slice consisting of the given characters
-            opt(is_a(REMAINING_CHARS)),
+            opt(is_a(remaining_chars)),
         ),
     )(i)
 }
